package com.ld.hpfs.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.ld.hpfs.common.jackson.JackJson;
import com.ld.hpfs.common.jackson.JacksonHelper;
import com.ld.hpfs.common.utils.Const;
import com.ld.hpfs.dao.ExpressPrintMapper;
import com.ld.hpfs.pojo.CustomerContact;
import com.ld.hpfs.pojo.TaskRequest;
import com.ld.hpfs.pojo.TaskResponse;
import com.ld.hpfs.pojo.User;
import com.ld.hpfs.service.ExpressPrintService;
import com.ld.hpfs.service.ReportService;
import com.ld.hpfs.web.controller.HttpRequest;
import com.ld.hpfs.web.interseptor.WebConstants;
import com.lowagie.tools.Executable;

@Service
public class ExpressPrintServiceImpl implements ExpressPrintService{
	
	private static final Logger logger = LoggerFactory.getLogger(ExpressPrintServiceImpl.class);
	private String expressCode;
	@Autowired
	private ExpressPrintMapper expressPrintMapper;
	
	//导出快递单
	@Autowired
	private ReportService      reportService;
	//任务id
	private static String taskID = "";
	private static int printway = 0;
	
	/**
	 *获取快递单打印信息接口实现
	 */
	@Override
	public ArrayList<HashMap<String, Object>> getExpressPrintList(HashMap<String,Object> inputparam){
		int count = expressPrintMapper.getExpressPrintListCount(inputparam);
		if(count == 0){
			return null;
		}else{
			inputparam.put("pageCount", count);
			return expressPrintMapper.getExpressPrintList(inputparam);
		}
	}

	/**
	 * 获取快递单收件人信息接口实现
	 */
	@Override
	public List<CustomerContact> getContactList(HashMap<String,Object> inputparam) {
		List<CustomerContact> results = new ArrayList<CustomerContact>();
		ArrayList<HashMap<String,Object>> contacts;
		try{
			contacts = expressPrintMapper.getContactList(inputparam);
			}
		catch(Exception e){
			logger.error(e.getMessage());
			return null;
		}
		for(int i=0; i<contacts.size(); i++){    		
			HashMap<String, Object> param = contacts.get(i);
			CustomerContact contact = new CustomerContact();
			contact.setContact_id(Integer.parseInt(param.get("contact_id").toString()));
			contact.setCust_id(Integer.parseInt(param.get("cust_id").toString()));
			contact.setContact_name(param.get("contact_name").toString());
			contact.setGroup_id(Integer.parseInt(param.get("group_id").toString()));
			contact.setContact_company_name(param.get("contact_company_name").toString());
			contact.setContact_address(param.get("contact_address").toString());
			contact.setContact_tel(param.get("contact_tel").toString());
			contact.setContact_city(param.get("contact_city").toString());
			contact.setRemark(param.get("remark").toString());
			contact.setRef01(param.get("ref01").toString());
			contact.setRef02(param.get("ref02").toString());
			contact.setRef03(param.get("ref03").toString());
			contact.setRef04(param.get("ref04").toString());
			contact.setRef05(param.get("ref05").toString());
			contact.setUpdate_id(Integer.parseInt(param.get("update_id").toString()));
			contact.setUpdate_name(param.get("update_name").toString());
			contact.setUpdate_time(param.get("update_time").toString());
			contact.setContact_email(param.get("contact_email").toString());
			contact.setPhone_number(param.get("phone_number").toString());
			
			results.add(contact);
		}
	    return results;
	}
	
	/**
	 * 更新快递单信息
	 */
	@Override
	public int updateExpress(HashMap<String, Object> inputparam) {
		try{
			return expressPrintMapper.updateExpress(inputparam);
		}
		catch(Exception e){
			logger.error(e.getMessage());
			return 0;
		}
	}

	
	/**
	 * 获取快递单收件人信息接口实现
	 */
	@Override
	public List<CustomerContact> getIdContactList(HashMap<String,Object> inputparam) {
		List<CustomerContact> results = new ArrayList<CustomerContact>();
		ArrayList<HashMap<String,Object>> contacts;
		try{
			contacts = expressPrintMapper.getIdContactList(inputparam);
			}
		catch(Exception e){
			logger.error(e.getMessage());
			return null;
		}
		for(int i=0; i<contacts.size(); i++){    		
			HashMap<String, Object> param = contacts.get(i);
			CustomerContact contact = new CustomerContact();
			contact.setId(Integer.parseInt(param.get("id").toString()));
			contact.setContact_id(Integer.parseInt(param.get("contact_id").toString()));
			contact.setCust_id(Integer.parseInt(param.get("cust_id").toString()));
			contact.setContact_name(param.get("contact_name").toString());
			contact.setGroup_id(Integer.parseInt(param.get("group_id").toString()));
			contact.setContact_company_name(param.get("contact_company_name").toString());
			contact.setContact_address(param.get("contact_address").toString());
			contact.setContact_tel(param.get("contact_tel").toString());
			contact.setContact_city(param.get("contact_city").toString());
			contact.setRemark(param.get("remark").toString());
			contact.setRef01(param.get("ref01").toString());
			contact.setRef02(param.get("ref02").toString());
			contact.setRef03(param.get("ref03").toString());
			contact.setRef04(param.get("ref04").toString());
			contact.setRef05(param.get("ref05").toString());
			contact.setUpdate_id(Integer.parseInt(param.get("update_id").toString()));
			contact.setUpdate_name(param.get("update_name").toString());
			contact.setUpdate_time(param.get("update_time").toString());
			contact.setContact_email(param.get("contact_email").toString());
			contact.setPhone_number(param.get("phone_number").toString());
			
			results.add(contact);
		}
	    return results;
	}
	
	/**
	 * 获取联系人信息接口实现
	 */
	@Override
	public ArrayList<HashMap<String, Object>> getContacts(
			HashMap<String, Object> param) {
		return expressPrintMapper.getContacts(param);
	}

	/**
	 * 清空快递单打印临时表数据接口实现
	 */
	@Override
	public int deleteExpressPrintRpt(HashMap<String, Object> param) {
		try{
			return expressPrintMapper.deleteExpressPrintRpt(param);
		}
		catch(Exception e){
			logger.error(e.getMessage());
			return 0;
		}
	}
	/**
	 * 插入一条数据到快递单临时表接口实现
	 * @param param
	 */
	@Override
	public int insertExpressPrintRpt(HashMap<String, Object> param) {
		try{
			return expressPrintMapper.insertExpressPrintRpt(param);
		}
		catch(Exception e){
			logger.error(e.getMessage());
			return 0;
		}
	}

	
	/**
	 * 获取快递单打印临时表名
	 * @param param
	 * @return
	 */
	@Override
	public String getExpressPrintTableName(HashMap<String,Object> param){
		try{
			return expressPrintMapper.getExpressPrintTableName(param);
		}
		catch(Exception e){
			logger.error(e.getMessage());
			return "";
		}
	}
	/**
	 * 更新快递相关信息，并打印快递单
	 * @param session
	 * @param request
	 * @param response
	 * @param writer
	 */
	@Override
	public void printExpress(HttpSession session,
			HttpServletRequest request,
			HttpServletResponse response,
			PrintWriter writer,
			int check) {
		try{
			// 分割出要打印的快递单的id存入ids数组
	    	String[] ids = request.getParameter("ids").split("\\|");
	    	
			// 把id做成参数需要的HashMap结构
	    	List<HashMap<String,String>> idlist = new ArrayList<HashMap<String,String>>();
			HashMap<String,String> map= new HashMap<String,String>();
			for(int i=0;i<ids.length;i++){
				map = new HashMap<String,String>();
				map.put("id", ids[i]);
				idlist.add(map);
			}
			printway = Integer.parseInt(request.getParameter("printway"));
			HashMap<String,Object> param = new HashMap<String,Object>();
			param.put("ids", idlist);
			
			List<CustomerContact> result = getIdContactList(param);
			
			// 进行快递单合并
			List<CustomerContact> list = new ArrayList<CustomerContact>();
			
			//获取参数中快递公司id
			String express = request.getParameter("express");
			
			//获取参数中起始快递单号
			String expressStartNoStr = request.getParameter("expressStartNo");
			//用来记录数字位数长度变量
			int expressLength = 0;
			//截取快递单后几位的数字作为连号
			for(int i=expressStartNoStr.length()-1;i>=0;i--){
				if(expressStartNoStr.charAt(i)>=48 && expressStartNoStr.charAt(i)<=57){
					expressLength++;
				}
			}
			long expressStartNo = request.getParameter("expressStartNo").equals("") ? -1 :
				Long.parseLong(request.getParameter("expressStartNo").substring(expressStartNoStr.length()-expressLength));
			//快递单号前几位的字母
			String expressNoHead = "";
			if(expressStartNoStr.length() != expressLength){
				expressNoHead = expressStartNoStr.substring(0, expressStartNoStr.length() - expressLength);
			}
			
			//获取参数中打印数量
			int printNum = request.getParameter("printNum").equals("") ? result.size() : Integer.parseInt(request.getParameter("printNum"));
			
			//获取参数中合并参数
			String combine = request.getParameter("combine");
			
			/*
			 * 合并类型
			 * 0：客户
			 * 1：客户+收件人
			 * 2：不合并
			 * 如有输入起始快递号则更新记录的快递号
			 * 如有输入打印张数，则更新特定数量的快递号\
			 * 借用Group_id字段作为记录发票数量的字段
			 */
			if(combine.equals("0")){
				list.add(result.get(0));
				printNum--;
				
				// 更新快递单号
				if(!expressStartNoStr.equals("")){
					updateExpressNo(result,0,expressStartNo,expressLength,expressNoHead,express);
				}
				
				//根据客户id从result合并数据到list
				if(result.size()>1){
					for(int i=1;i<result.size();i++){
						if(result.get(i).getCust_id() == result.get(i-1).getCust_id()){
							list.get(list.size()-1).setGroup_id(list.get(list.size()-1).getGroup_id()+1);
							
							// 更新快递单号
							if(!expressStartNoStr.equals("")){
								updateExpressNo(result,i,expressStartNo,expressLength,expressNoHead,express);
							}
						}
						else{
							if(printNum>0){
								list.add(result.get(i));
								printNum--;
								expressStartNo++;
								
								// 更新快递单号
								if(!expressStartNoStr.equals("")){
									updateExpressNo(result,i,expressStartNo,expressLength,expressNoHead,express);
								}
							}
							else{
								break;
							}
						}
					}
				}
			}
			else if(combine.equals("1")){
				list.add(result.get(0));
				printNum--;
				
				// 更新快递单号
				if(!expressStartNoStr.equals("")){
					updateExpressNo(result,0,expressStartNo,expressLength,expressNoHead,express);
				}
				
				//根据客户id和联系人id从result合并数据到list
				if(result.size()>1){
					for(int i=1;i<result.size();i++){
						if(result.get(i).getCust_id() == result.get(i-1).getCust_id() && result.get(i).getContact_id() == result.get(i-1).getContact_id()){
							list.get(list.size()-1).setGroup_id(list.get(list.size()-1).getGroup_id()+1);
							
							// 更新快递单号
							if(!expressStartNoStr.equals("")){
								updateExpressNo(result,i,expressStartNo,expressLength,expressNoHead,express);
							}
						}
						else{
							if(printNum>0){
								list.add(result.get(i));
								printNum--;
								expressStartNo++;
							
								// 更新快递单号
								if(!expressStartNoStr.equals("")){
									updateExpressNo(result,i,expressStartNo,expressLength,expressNoHead,express);
								}
							}
							else{
								break;
							}
						}
					}
				}
			}
			else{
				for(int i=0;i<printNum;i++){
					list.add(result.get(i));
					// 更新快递单号
					if(!expressStartNoStr.equals("")){
						updateExpressNo(result,i,expressStartNo,expressLength,expressNoHead,express);
						expressStartNo++;
					}
				}
			}
			
			// 打印合并好的快递单
			// 获取快递公司对应的临时表
			HashMap<String, Object> tableNameParam = new HashMap<String, Object>();
			tableNameParam.put("express_id", express);
			String table = getExpressPrintTableName(tableNameParam);
			// 清空快递单打印临时表
			HashMap<String, Object> deleteParam  = new HashMap<String, Object>();
			deleteParam.put("table", table);
			deleteExpressPrintRpt(deleteParam);
			// 插入数据到快递单打印临时表
			for(int i=0;i<list.size();i++){
				HashMap<String, Object> insertParam  = new HashMap<String, Object>();
				insertParam.put("contact_id", list.get(i).getContact_id());
				insertParam.put("remark", list.get(i).getRemark());
				insertParam.put("table",table);
				insertParam.put("company_id", session.getAttribute(WebConstants.CURRENT_COMPANY));
				insertExpressPrintRpt(insertParam);
			}
			//导出水晶报表
			String report_name = "快递单";
		 	String report_param = "report_name=" + table.substring(8);
		 	String detail = "起始快递号:" + expressStartNoStr;
			HashMap<String,Object> paramPDF = new HashMap<String,Object>();
			HashMap<String,Object> resultPDF = new HashMap<String,Object>();
//			ArrayList<HashMap<String,Object>> logs = new ArrayList<HashMap<String,Object>>();		
			response.setContentType("text/plain;charset=UTF-8");
				User user = (User)session.getAttribute(WebConstants.CURRENT_USER);
				paramPDF.put("report_name",report_name );
				paramPDF.put("report_param",report_param + ";user_id=" + user.getUserId());
				paramPDF.put("creator_id", user.getUserId());
				paramPDF.put("companyId", Integer.parseInt(session.getAttribute(WebConstants.CURRENT_COMPANY).toString()));		
				paramPDF.put("detail", detail);
				String lang = session.getAttribute(WebConstants.CURRENT_LANG).toString();
				//int check = reportService.insertReportTaskGridList(paramPDF);   //插入任务			
				if(check == 0){		
					 int id = reportService.getReportTaskId();		  //获取任务ID
					 if(id != -1){						 				 							
						 StringBuilder impUrl = new StringBuilder();
	  			 		 impUrl.append(Const.PROPERTIES.getProperty("import.server.url"))
	  			 		 .append(Const.PROPERTIES.getProperty("import.server.report_method")).append(id).append("&lang=").append(lang);
						 logger.debug("Import URL = {}", impUrl);
						 HttpClient httpclient = new DefaultHttpClient();
						 HttpGet httpget = new HttpGet(impUrl.toString());
						 HttpResponse response1 = httpclient.execute(httpget);
						 HttpEntity entity = response1.getEntity();
						 if (entity != null) {
							 InputStream instream = entity.getContent();
							 try {
								 String res = EntityUtils.toString(entity);
								 logger.debug(res);
								 Map<String, Object> retMap = JackJson.fromJsonToObject(res, Map.class);
								 String resultCode = retMap.get("ResultCode").toString();                   
								 if(resultCode.equals("0")){
									 resultPDF.put("resultcode",0);
								 }else{
								  String resultMsg = retMap.get("ResultMsg").toString();
								  resultPDF.put("resultcode",resultMsg);
								 }	
							}finally{
								instream.close();
							}
					    }
						 
						//定时检查PDF生成情况，生成完毕则打印
						Timer timer = new Timer();
						
						//设置taskID
						taskID=Integer.toString(id);
						
						//在5秒后执行此任务,每次间隔2秒
						timer.schedule(new printTask(), 5000, 2000);
					
				    }else{
					  resultPDF.put("resultcode",9);
				    }
			   }else{
				  resultPDF.put("resultcode",9);
			     }  
				String returnMsg = JackJson.fromObjectToJson(resultPDF);
				logger.debug("{}", returnMsg);
				writer.print(returnMsg);	 
		}
		catch(Exception e){
			logger.error(e.getMessage());
			writer.print("{\"resultcode\":\"-1\"}");
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		}
	}
	
	/**
     * 打印快递单方法中更新快递单号方法
     * @param result
     * @param i
     * @param expressStartNo
     */
    private void updateExpressNo(
    		List<CustomerContact> result,
    		int i,
    		long expressStartNo,
    		int expressLength,
    		String expressNoHead,
    		String express){
    	HashMap<String, Object> updateParam = new HashMap<String, Object>();
		updateParam.put("id", result.get(i).getId());
		//输入快递单号则更新快递单号
		if(expressLength > 0){
			// 前补零至数字长度位数
			String tempExpressNo = "";
			for(int j=0;j<(expressLength-String.valueOf(expressStartNo).length());j++){
				tempExpressNo+="0";
			}
			String EpxressNo = expressNoHead + tempExpressNo+String.valueOf(expressStartNo);
			if (!EpxressNo.equals(expressCode)) {
				//TODO 推送快递信息
				String expressCpn = expressPrintMapper.getExpressCpn(express);
				HashMap<String, Object> param = new HashMap<String, Object>();
				param.put("express_no", EpxressNo);
				param.put("express_cpn", expressCpn);
				doExpressImpl(param);
			}
			expressCode = EpxressNo;
			updateParam.put("expressNo", EpxressNo);
		}
		//更新票据状态参数
		updateExpress(updateParam);
    }
    
    // 调用快递接口
    public void doExpressImpl(HashMap<String, Object> document) {
		HashMap<String, Object> result = new HashMap<String, Object>();
		try {
			// 回执url
			String callbackurl = Const.PROPERTIES.getProperty("callbackurl");
			// 推送秘钥
			String key = Const.PROPERTIES.getProperty("key");
			// 快递公司
			String exp_company = document.get("express_cpn").toString();
			// 快递单号
			String exp_no = document.get("express_no").toString();
			TaskRequest req = new TaskRequest();
			req.setCompany(exp_company);
			req.setNumber(exp_no);
			req.getParameters().put("callbackurl", callbackurl);
			req.setKey(key);
			HashMap<String, String> p = new HashMap<String, String>();
			p.put("schema", "json");
			p.put("param", JacksonHelper.toJSON(req));
			String returnData = HttpRequest.postData(
					Const.PROPERTIES.getProperty("expressserver"), p, "UTF-8");
			TaskResponse resp = JacksonHelper.fromJSON(returnData,
					TaskResponse.class);
			if (resp.getReturnCode() == 200) {
				result.put("expressCode", 0);
				System.out.println(returnData);
			} else {
				result.put("expressCode", 1);
				System.out.println(returnData);
			}
		} catch (Exception e) {
			System.out.println(e);
		}
	}
    
    //连接打印机打印pdf（可选择打印机）
    @SuppressWarnings("static-access")
	public void printer(String url){
    	// 如果打印方式为0直接将pdf下载到本地
    	if (printway != 0) {
    		try {
    			Executable ex = new Executable();
    			ex.printDocumentSilent(url);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }
    //连接打印机打印pdf（自动选择打印机）
    public void autoPrinter(String url){
    	File file = new File(url);
        //构建打印请求属性集
        PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();  
        //设置打印格式
        DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;          
        //查找所有的可用的打印服务    
        PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);   
        //如果找到打印机
        if( printService.length > 0 ){
          DocPrintJob job = printService[1].createPrintJob();
          FileInputStream fis = null;
          try {
            fis = new FileInputStream(file);
            //构建文件属性
            DocAttributeSet das = new HashDocAttributeSet();
            Doc doc = new SimpleDoc(fis, flavor, das);
            job.print(doc, pras);
          } catch (FileNotFoundException e) {
            e.printStackTrace();
          } catch (PrintException e) {
            e.printStackTrace();
          }
        }
    }

    /**
	 * 获取生成的快递单PDF的URL
	 */
	@Override
	public String getExpressURL(String id) {
		try{
			return expressPrintMapper.getExpressURL(id);
		}
		catch(Exception e){
			logger.error(e.getMessage());
			return "";
		}
	}
	
	public String getURL(String id){
		return expressPrintMapper.getExpressURL(id);
	}
	
	// 打印定时器类
	public class printTask extends java.util.TimerTask {
		@Override
		public void run() {
			String url = getURL(taskID);
			
			if(!url.isEmpty()){
				String basepath = Const.REAL_PATH;
				basepath = basepath.substring(0, basepath.indexOf("tomcat-7.0"));
				//<a href="http://localhost:1305/reports/1386170669/4816/customers_bill.pdf" target="blank">customers_bill.pdf</a>
				url = "Apache/htdocs" + url.substring(url.indexOf("/reports"), url.indexOf(".pdf")) + ".pdf";
				url = basepath + url;
				System.out.println("url:"+url);
				printer(url);
				taskID="0";
				cancel();
			}
		}
	}
}


